package com.ww.springboot.boot.algorithm.leetcode1;

/**
 * 描述：
 *
 * @author 🧑 ‍wanwei
 * @since 2022-03-24 11:03
 */
public class AZ661图片平滑器2 {

    public static void main(String[] args) {
        int[][] img = {{100,200,100},{200,50,200},{100,200,100}};
        int[][] imgNew = imageSmoother(img);

        PrintUtil.print(imgNew);
    }

    /**
     * 自身及周围8个点的和/9
     * <p>
     * 1.优化
     * 相邻的节点其实是有共同节点的
     * 遍历i行时 可以将i-1 i i+1计算并存储 避免多余的计算
     *
     * @param img
     * @return
     */
    public static int[][] imageSmoother(int[][] img) {
        int[][] result = new int[img.length][img[0].length];
        int[][] dp = new int[img.length][img[0].length];
        for (int i = 0; i < img.length; i++) {
            dp[i][0] = getDp(img, i, 0);
            for (int j = 0; j < img[0].length; j++) {
                result[i][j] = getResult(img, i, j, dp);
            }
        }
        return result;
    }

    /**
     * 计算 i,j 上下三行的总和
     *
     * @param img
     * @param i
     * @param j
     * @return
     */
    private static int getDp(int[][] img, int i, int j) {
        int result = 0;
        result += img[i][j];
        if (i - 1 >= 0) {
            result += img[i - 1][j];
        }
        if (i + 1 < img.length) {
            result += img[i + 1][j];
        }
        return result;
    }

    private static int getResult(int[][] img, int i, int j, int[][] dp) {
        if (j + 1 < img[0].length) {
            dp[i][j + 1] = getDp(img, i, j + 1);
        }
        int size;
        Boolean flag1 = i == 0 || i == img.length - 1;
        Boolean flag2 = j == 0 || j == img[0].length - 1;

        if (img.length == 1 && img[0].length == 1) {
            size = 1;
        } else if (img.length == 1 || img[0].length == 1) {
            if (flag1 && flag2) {
                size = 2;
            } else {
                size = 3;
            }
        } else {
            if (flag1 && flag2) {
                size = 4;
            } else if (!flag1 && !flag2) {
                size = 9;
            } else {
                size = 6;
            }
        }

        int total = 0;
        for (int k = -1; k <= 1; k++) {
            if (j + k < 0 || j + k > img[0].length - 1) {
                continue;
            }
            total += dp[i][j + k];
        }
        return total / size;
    }
}
